#[allow(unused_macros)]
macro_rules! auto_reject {
    ($t:ident,$block:expr) => {
        async {
            let t = $block.await;
            if t.is_err() {
                $t.rollback().await.unwrap();
            } else {
                $t.commit().await.unwrap();
            }
            t
        }.await
    };
}
macro_rules! declare_dao {
    ($dao_name:ident {$($field_name:ident:$field_type:ty),*}) => {
        
        #[derive(Debug,Clone,sqlx::FromRow,serde::Serialize,serde::Deserialize)]
        pub struct $dao_name {
            $(
                pub $field_name:$field_type,
            )*
        }
    };
    ($dao_name:ident {$($field_name:ident:$field_type:ty),*};$table_name:literal) => {
        declare_dao!($dao_name {$($field_name:$field_type),*});
        impl $dao_name {
            #[inline(always)]
            pub fn get_table_name() -> &'static str {
                $table_name
            }
        }
    };
    ($dao_name:ident {$($field_name:ident:$field_type:ty),*};$table_name:literal;$pk_type:ty;$($pk_step:ident).*) => {
        declare_dao!($dao_name {$($field_name:$field_type),*};$table_name);
        impl $crate::dao::PrimaryKey<$pk_type> for $dao_name {
            fn get_pk(&self) -> $pk_type {
                self.$($pk_step).*
            }
        }
        impl $crate::dao::PrimaryKey<$pk_type> for &$dao_name {
            fn get_pk(&self) -> $pk_type {
                self.$($pk_step).*
            }
        }
    };
}